import 'dart:async';

import 'package:number_spark_flutter/network/ns_api.dart';
import 'package:number_spark_flutter/utils/ns_toast_utils.dart';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/services.dart';
import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
import 'package:get/get.dart';
import 'package:sp_util/sp_util.dart';

class NSInAppPurchaseModel {
  String? productId;
  String? transactionId;
  String? receiptData;
  Function? successBlock;
  Function? cancelBlock;
  String? goodsOrderKey;
  String? orderNo;
  String? tradeNo;

  NSInAppPurchaseModel({
    this.productId,
    this.transactionId,
    this.receiptData,
    this.successBlock,
    this.cancelBlock,
    this.goodsOrderKey,
    this.orderNo,
    this.tradeNo,
  });

  NSInAppPurchaseModel.fromJson(Map<dynamic, dynamic> json) {
    productId = json['productId'];
    transactionId = json['transactionId'];
    receiptData = json['receiptData'];
    goodsOrderKey = json['goodsOrderKey'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['productId'] = productId;
    data['transactionId'] = transactionId;
    data['receiptData'] = receiptData;
    data['goodsOrderKey'] = goodsOrderKey;
    return data;
  }
}

class NSInAppPurchaseUtil {
  factory NSInAppPurchaseUtil() => _getInstance();

  static NSInAppPurchaseUtil get instance => _getInstance();
  static NSInAppPurchaseUtil? _instance;

  static NSInAppPurchaseUtil _getInstance() {
    if (_instance == null) {
      initPlatformState();
      _instance = NSInAppPurchaseUtil._internal();
    }
    return _instance!;
  }

  NSInAppPurchaseModel? selectedModel;

  NSInAppPurchaseUtil._internal();

  static StreamSubscription? _purchaseUpdatedSubscription;
  static StreamSubscription? _purchaseErrorSubscription;

  static Future<void> initPlatformState() async {
    var result = await FlutterInappPurchase.instance.initialize();
    // 更新购买订阅消息
    _purchaseUpdatedSubscription = FlutterInappPurchase.purchaseUpdated.listen((productItem) {
      getPurchases();
    });
    // 购买报错订阅消息
    _purchaseErrorSubscription = FlutterInappPurchase.purchaseError.listen((purchaseError) {
      BotToast.closeAllLoading();
      NSInAppPurchaseUtil().selectedModel?.cancelBlock?.call();
      if (purchaseError?.code == 'E_USER_CANCELLED') {
        NSToast.show('Pay Cancel');
      } else {
        NSToast.show('Pay Error');
      }
    });
    getUnHandleList();
  }

  static Future<bool> getUnHandleList({bool revertSubscription = false}) async {
    List<PurchasedItem>? unHandle = await FlutterInappPurchase.instance.getPendingTransactionsIOS();
    if (unHandle?.isNotEmpty == true) {
      await checkOrderForService(unHandle!.first, revertSubscription: revertSubscription);
      return true;
    } else if (revertSubscription) {}
    return false;
  }

  Future getProduct(NSInAppPurchaseModel model) async {
    List<IAPItem> items = await FlutterInappPurchase.instance.getProducts([model.productId ?? '']);
    IAPItem? selectedItem;
    for (var item in items) {
      if (item.productId == model.productId) {
        selectedItem = item;
      }
    }
    if (selectedItem != null) {
      selectedModel = model;
      _requestPurchase(selectedItem);
    } else {
      NSToast.show('The product not exists');
      BotToast.closeAllLoading();
    }
  }

  void _requestPurchase(IAPItem item) async {
    var result = await FlutterInappPurchase.instance.requestPurchase(item.productId ?? '');
    print(result);
    await FlutterInappPurchase.instance.finalize();
  }

  static Future getPurchases() async {
    _purchaseErrorSubscription?.resume();
    _purchaseUpdatedSubscription?.resume();
    try {
      List<PurchasedItem> items = await FlutterInappPurchase.instance.getAvailablePurchases() ?? [];
      //根据productId 取出所有
      List<PurchasedItem> tempList = items.where((element) => element.productId == NSInAppPurchaseUtil().selectedModel?.productId).toList();
      //根据transactionDate 排序
      tempList.sort((a, b) => (b.transactionDate?.millisecondsSinceEpoch ?? 0).compareTo(a.transactionDate?.millisecondsSinceEpoch ?? 0));
      if (tempList.isNotEmpty) {
        await checkOrderForService(tempList.first);
      } else {}
      BotToast.closeAllLoading();
    } on PlatformException catch (error) {
      BotToast.closeAllLoading();
      if (error.code == 'E_UNKNOWN') {
      } else {}
    }
  }

  static Future<void> checkOrderForService(PurchasedItem? purchasedItem, {bool revertSubscription = false}) async {
    Map<String, dynamic> params = {
      'orderNo': NSInAppPurchaseUtil().selectedModel?.orderNo,
      'payload': purchasedItem?.transactionReceipt,
      'transactionId': purchasedItem?.originalTransactionIdentifierIOS ?? purchasedItem?.transactionId,
      'type': 1
    };
    NSResponseData responseData = await NSApi.checkOrder.post(params);
    if (responseData.isSuccess()) {
      NSToast.show('Buy success');
      FlutterInappPurchase.instance.finishTransactionIOS(purchasedItem?.transactionId ?? '');
      NSInAppPurchaseUtil().selectedModel?.successBlock?.call();
    }
  }
}
